<script setup>
import {onMounted, provide, reactive, ref} from 'vue'
import PinList from "./PinList.vue";
import useNatureSizeStore from "@/store/natureSize.js";
import usePatternStore from "@/store/pattern";
import useLocationStore from "@/store/location.js";
import useAdminStore from "@/store/admin.js";
import useUUIDUtil from '@/utils/uuid.js'
import defaultImg from '@/assets/map04.jpg'

const useAdmin = useAdminStore()

const useUUID = useUUIDUtil()
const usePattern = usePatternStore()
const useLocation = useLocationStore()
const useNatureSize = useNatureSizeStore()
// 初始化本地缓存
const rate = ref(1)
// 定义图片相对（0，0）点的坐标的偏移量
const mx = ref(0)
const my = ref(0)
// 定义鼠标的坐标信息
const clientX = ref(0)
const clientY = ref(0)
const angle = ref(0)
const imgSizeObj = reactive({
  width: 0,
  height: 0
})
const imgRef = ref(defaultImg)

const pinNodes = ref([])
window.onmousemove = function (e) {
  // 计算鼠标移动的距离
  clientX.value = e.clientX
  clientY.value = e.clientY
  angle.value = Math.atan2(e.clientY, e.clientX) * 180 / Math.PI
}
// 页面加载
onMounted(async () => {
  await getNetworkBgImg()
  await init()
})
const getNetworkBgImg = async () => {
  const {path} = await useAdmin.loadBgImg()
  console.log("path",path)
  imgRef.value = path
}
const naturalHeight = ref(0)
const naturalWidth = ref(0)
const init = async function () {
  let img = document.querySelector("#img")
  //获取浏览器的高度
  let clientHeight = document.documentElement.clientHeight
  // 设置图片高度为屏幕高度
  img.style.height = clientHeight + "px"
  // 屏幕大小
  console.log("屏幕大小", document.documentElement.clientWidth, document.documentElement.clientHeight)
  // 获取一开始加载后的图片宽高并保存
  imgSizeObj.width = img.width
  imgSizeObj.height = img.height
  // 因为获取图片的真实高度和宽度需要一定时间，这里采用promise异步的方式获取
  await Promise.all([new Promise((resolve, reject) => {
    img.onload = async () => {
      naturalHeight.value = img.naturalHeight
      naturalWidth.value = img.naturalWidth
      console.log("img.naturalHeight", img.naturalHeight, "img.naturalWidth", img.naturalWidth)
      // 图片的宽高比
      let imgRate = img.naturalWidth / img.naturalHeight
      useNatureSize.setImgRate(imgRate)
      // 保存的位置信息始终是相对真实图片大小的位置，这样当浏览器的尺寸发生变化时，图片的位置也不会发生变化
      let truthForRate = img.naturalHeight / clientHeight

      if (useNatureSize.getRate() === null) {
        useNatureSize.setRate(truthForRate)
      }
      let relativeRate = truthForRate / useNatureSize.getRate()
      let currentPinNodes = await useLocation.getPositions()
      pinNodes.value = currentPinNodes.map(item => {
        return {
          uuid: item.uuid,
          icon: item.icon,
          x: item.x / relativeRate,
          y: item.y / relativeRate,
          txt: item.txt,
          link: item.link
        }
      })
      useNatureSize.setNatureSize(img.naturalWidth, img.naturalHeight)
      handleTouch(img)
      resolve()
    }
  })])
}
const resetSize = () => {
  window.location.reload()
}


let store = {
  scale: 1,
  center: {}
}
// 监听touch事件处理
const handleTouch = (img) => {
  // 阻止浏览器默认事件
  document.ontouchmove = (e) => {
    e.preventDefault()
  }
  document.ontouchstart = (e) => {
    e.preventDefault()
  }
  document.ontouchend = (e) => {
    e.preventDefault()
  }
  document.ontouchcancel = (e) => {
    e.preventDefault()
  }
  // 自定义缩放常数，距离每放大或者缩小10，放大或者缩小1倍
  const SCALE_NUM = 10
  // 计算两点之间的距离
  const getDistance = (p1, p2) => {
    let x = p1.pageX - p2.pageX
    let y = p1.pageY - p2.pageY
    return Math.sqrt(x * x + y * y)
  }
  img.ontouchstart = (e) => {
    // 取消默认事件
    e.preventDefault()
    // 情况1：单指点击
    if (e.touches.length === 1) {
      if (!(store.pageX && store.pageY)) {
        store.pageX = e.touches[0].pageX
        store.pageY = e.touches[0].pageY
      }
    }
    // 情况2：双指点击
    if (e.touches.length === 2) {
      //获得双指的中心位置，如果已经有中心点，不再计算
      if (!(store.center.x && store.center.y && store.distance)) {
        store.center.x = (e.touches[0].pageX + e.touches[1].pageX) / 2
        store.center.y = (e.touches[0].pageY + e.touches[1].pageY) / 2
        store.distance = getDistance(e.touches[0], e.touches[1])
      }
      store.distance = getDistance(e.touches[0], e.touches[1])
    }
  }
  img.ontouchmove = (e) => {
    // e.preventDefault()
    if (e.touches.length === 1) {
      //   图片跟随偏移
      let x = e.touches[0].pageX - store.pageX
      let y = e.touches[0].pageY - store.pageY
      store.pageX = e.touches[0].pageX
      store.pageY = e.touches[0].pageY
      img.style.left = img.offsetLeft + x + "px"
      img.style.top = img.offsetTop + y + "px"

      mx.value = img.offsetLeft
      my.value = img.offsetTop
    }
    //   处理缩放
    if (e.touches.length === 2) {


      //   1、获取2指间的距离
      let currentDistance = getDistance(e.touches[0], e.touches[1])
      //   当前距离与store中的distance的差值
      let diff = currentDistance - store.distance
      //   2、计算缩放大小
      let size = diff / SCALE_NUM
      //  3、计算缩放后的图片尺寸
      let imgWidth = img.width + size
      rate.value = imgWidth / imgSizeObj.width
      // 3-1、高度根据imgRate计算,按照图片的宽高比进行缩放
      let imgRate = useNatureSize.getImgRate()
      let imgHeight = imgWidth / imgRate
      // 附加：判断当前的img的高度如果已经小于了屏幕的高度，只允许放大，不允许缩小
      if (imgHeight < document.documentElement.clientHeight) {
        // 回写，防止图片缩小
        img.style.width = imgSizeObj.width + "px"
        img.style.height = imgSizeObj.height + "px"
        // 回写rate
        rate.value = imgSizeObj.height / document.documentElement.clientHeight
        return
      }
      // 4、获取当前的图片宽高
      let currentImgWidth = img.width
      let currentImgHeight = img.height
      let currentImgOffsetLeft = img.offsetLeft
      let currentImgOffsetTop = img.offsetTop
      //  4-1、重新赋值
      img.style.width = imgWidth + "px"
      img.style.height = imgHeight + "px"

      //   解决2个问题，1是图片放大的中心点为store.center，2是pin标签需要保持相对位置不变
      // 5、计算图片放大后的偏移量
      let newImgOffsetLeft = currentImgOffsetLeft - (store.center.x - currentImgOffsetLeft) * (imgWidth / currentImgWidth - 1)
      let newImgOffsetTop = currentImgOffsetTop - (store.center.y - currentImgOffsetTop) * (imgHeight / currentImgHeight - 1)
      // 6、重新设置图片的偏移量，抵消由于图片放大导致的偏移
      img.style.left = newImgOffsetLeft + "px"
      img.style.top = newImgOffsetTop + "px"

      //   7、动态调整mx和my，保持pin相对图片的位置不变
      mx.value = img.offsetLeft
      my.value = img.offsetTop
    }
  }
  img.ontouchend = (e) => {
    e.preventDefault()
    delete store.pageX
    delete store.pageY
    //   删除中心位置
    delete store.center.x
    delete store.center.y
    //   删除距离
    delete store.distance
  }
  img.ontouchcancel = (e) => {
    e.preventDefault()
    delete store.pageX
    delete store.pageY
    //   删除中心位置
    delete store.center.x
    delete store.center.y
    //   删除距离
    delete store.distance
  }
}
const eventContainerClick = (e) => {
  if (usePattern.modal !== "edit") {
    return
  }

  let img = document.querySelector("#img")
  let x = (e.clientX - img.offsetLeft) / rate.value
  let y = (e.clientY - img.offsetTop) / rate.value
  const data = {uuid: useUUID.getUUID(), x, y, txt: "", icon: '', link: '', newPin: true}
  pinNodes.value.push(data)
  // 手动滚动一小段距离onwheelLen
  let onwheelLen = 1
//   执行一次滚动事件
  setTimeout(() => {
    let e1 = new WheelEvent("wheel", {deltaY: onwheelLen})
    window.dispatchEvent(e1)
  }, 10)
  //   执行一次滚动事件
  setTimeout(() => {
    let e2 = new WheelEvent("wheel", {deltaY: -onwheelLen})
    window.dispatchEvent(e2)
  }, 10)
}

// 监听浏览器尺寸的变化
window.onresize = () => {
  return (() => {
    //   从新刷新页面
    // window.location.reload()
  })()
}

// 定义一个方法，用于删除pin节点
const delPin = (obj) => {
  console.log("父级delPin", obj.uuid)
  let index = pinNodes.value.findIndex(item => {
    return item.uuid === obj.uuid
  })
  pinNodes.value.splice(index, 1)
}
provide("delPin", delPin)
</script>

<template>
  <div class="p-container" id="p-container">
    <img @click="eventContainerClick" id="img" style="overflow: hidden;position: absolute;" @onload="imgLoad"
         :src="imgRef"
         alt="">
    <component :is="PinList" :rate="rate" :nodes="pinNodes" :mx="mx" :my="my"/>
    <span
        style="color:red;position: absolute;bottom: 0;font-size: 12px;">({{ naturalHeight }},{{ naturalWidth }})</span>
  </div>

</template>

<style scoped>
.p-container {
  position: relative;
  width: 100vw;
  height: 100vh;
  max-width: 100vw;
  max-height: 100vh;
  background: #ddd;
  overflow: hidden;
  box-sizing: border-box;
  z-index: 0;
}
</style>